﻿/*===================================================
* CLR版本  : 4.0.30319.42000 
* 类名称   : UIComponent
* 文 件 名 : UIComponent 
* 类描述   :
* 创建人   : oream
* 创建时间 : 2018/3/8 1:54:42
* 修改人   : 
* 修改时间 :
* 版本： @version 1.0
=====================================================*/

using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace Hotfix
{
  [ObjectSystem]
  public class UIComponentSystem : ObjectSystem<UIComponent>, IAwake
  {
    public void Awake()
    {
      this.Get().Awake();
    }
  }

  public class UIComponent : Component
  {
    private Dictionary<EUitype, IUiFactory> dicUiFactory = new Dictionary<EUitype, IUiFactory>();
    private Dictionary<EUitype, UI> dicUis = new Dictionary<EUitype, UI>();

    private GameObject root;

    public void Awake()
    {
      this.root = GameObject.Find("Canvas");

      Type[] types = DllHelper.GetAllType();
      foreach (var type in types)
      {
        object[] tmpObj = type.GetCustomAttributes(typeof(UiFactoryAttribute), false);
        if (tmpObj.Length == 0) continue;
        if (!(tmpObj[0] is UiFactoryAttribute)) continue;

        UiFactoryAttribute uiFactoryAttribute = tmpObj[0] as UiFactoryAttribute;
        if (uiFactoryAttribute == null)
        {
          continue;
        }
        if (dicUiFactory.ContainsKey(uiFactoryAttribute.uiType))
        {
          Debug.LogError($"UI {uiFactoryAttribute.uiType.ToString()} 已经被添加了, 请检查!");
          throw new Exception($"UI {uiFactoryAttribute.uiType.ToString()} Existing!");
        }
        object tmp = Activator.CreateInstance(type);
        if (tmp == null) continue;

        IUiFactory uiFactory = tmp as IUiFactory;
        dicUiFactory.Add(uiFactoryAttribute.uiType, uiFactory);
      }
    }

    public UI Create(EUitype uiType)
    {
      try
      {
        UI ui = this.dicUiFactory[uiType].Create(this.GetParent<Scene>(), uiType, root);
        this.dicUis.Add(uiType, ui);
        ui.gameObject.transform.SetParent(root.transform);
        return ui;
      }
      catch (Exception e)
      {
        Debug.LogError(e.ToString());
        throw;
      }

    }

    public void Add(EUitype uiType, UI uI)
    {
      this.dicUis.Add(uiType, uI);
    }

    public void Remove(EUitype uiType)
    {
      UI ui;
      if (!this.dicUis.TryGetValue(uiType, out ui))
      {
        return;
      }
      ui.Dispose();
      this.dicUiFactory[uiType].Remove(uiType);
      this.dicUis.Remove(uiType);
    }

    public void RemoveAll()
    {
      foreach (EUitype type in this.dicUis.Keys.ToArray())
      {
        UI ui;
        if (!this.dicUis.TryGetValue(type, out ui))
        {
          continue;
        }
        this.dicUiFactory[type].Remove(type);
        this.dicUis.Remove(type);
        ui.Dispose();
      }
    }

    public UI Get(EUitype uiType)
    {
      UI uI;
      if (this.dicUis.TryGetValue(uiType, out uI))
      {
        return uI;
      }
      return null;
    }

    public List<EUitype> GetAllUiType()
    {
      return this.dicUis.Keys.ToList();
    }

  }
}
